﻿using System;
using System.Threading.Tasks;
using Pay.Core;
using Pay.DTO.xsft2;
using Flurl.Http;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using System.Net.Http;
using System.Linq;

namespace Pay.Service {
	public class Xsft2Sign {
		public Xsft2Sign() {
		}
#if DEBUG
		protected string api_url = " http://ipay.xsft.cn:8072";
		public const string key = "EA2486BE22140CF8214932E344A07215";
		public const string partner = "100056790";
#else
		protected string api_url = "http://ipay.xsft.cn:8072";
		public const string key = "C3EC3AEE22140CF8214932E34C3A2E34";
		public const string partner = "100056806";
#endif

		/// <summary>
		/// 请求
		/// </summary>
		/// <returns>The gateway.</returns>
		/// <param name="model">Model.</param>
		/// <typeparam name="T">The 1st type parameter.</typeparam>
		public async Task<T> PayGateway<T>(xsft2_req_base model, string url) where T : xsft2_resp_base, new() {
			var log = IocHelper.Get<ILogHelper>("info");
			model.merchantId = partner;
			var content = _sign(model);
			try {
				var formUrlContent = new FormUrlEncodedContent(content);
				var resp1 = await (api_url + url).PostAsync(formUrlContent).ReceiveString();
				log.Info(resp1);
				return resp1.ToObject<T>();
				//var resp = await api_url.PostJsonAsync(model).ReceiveJson<T>();
				//log.Info(resp.ToJson());
				//return resp;
			} catch (FlurlHttpException ex) {
				log.Error(ex.Message);
				return null;
			}
		}

		/// <summary>
		/// 签名
		/// </summary>
		/// <returns>The sign.</returns>
		/// <param name="model">Model.</param>
		private Dictionary<string, string> _sign(xsft2_req_base model) {
			var content = new Dictionary<string, string>();
			string json = model.ToJson();
			var collection = json.ToObject<Dictionary<string, object>>();
			collection = AsciiDictionary(collection);
			collection.Remove("sign");
			string result = string.Empty;
			foreach (var kv in collection) {
				if (kv.Value != null && !string.IsNullOrEmpty(kv.Value.ToString())) {
					result += "&" + kv.Key + "=" + kv.Value;
					content.Add(kv.Key, kv.Value.ToString());
				}
			}
			result = result.Trim('&');
			result += "&key=" + key;
			var log = IocHelper.Get<ILogHelper>("info");
			log.Info(result);
			string sign = SecureHelper.MD5(result);
			log.Info(sign);
			content.Add("sign", sign);
			return content;
		}

		/// <summary>
		/// 异步通知验签
		/// </summary>
		/// <param name="model">Model.</param>
		public bool VerifySign(xsft2_notify model) {
			var log = IocHelper.Get<ILogHelper>("info");
			var json = model.ToJson();
			log.Info(json);
			var collection = json.ToObject<Dictionary<string, object>>();
			collection = AsciiDictionary(collection);
			var sign = collection["sign"].ToString();
			collection.Remove("sign");
			string result = string.Empty;
			foreach (var kv in collection) {
				result += "&" + kv.Key + "=" + kv.Value;
			}
			result = result.Trim('&');
			result += "&key=" + key;
			log.Info(result);
			result = SecureHelper.MD5(result);
			log.Info(result);
			return result == sign;
		}

		/// <summary>
		/// 大小写排序
		/// </summary>
		/// <returns>The dictionary.</returns>
		/// <param name="sArray">S array.</param>
		public static Dictionary<string, object> AsciiDictionary(Dictionary<string, object> sArray) {
			Dictionary<string, object> asciiDic = new Dictionary<string, object>();
			string[] arrKeys = sArray.Keys.ToArray();
			Array.Sort(arrKeys, string.CompareOrdinal);
			foreach (var item in arrKeys) {
				object value = sArray[item];
				if (value != null && !string.IsNullOrEmpty(value.ToString()))
					asciiDic.Add(item, value);
			}
			return asciiDic;
		}
	}
}
